﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Rappelz.GameServer
{
    public class ExclusiveLogicLock
    {
        public class LockUnit
        {
            // UserDefinedType:   _LOCK_UNIT
            // Function       :     public void _LOCK_UNIT(const struct ExclusiveLogicLock<ArBoxCollision,XCriticalSection>::_LOCK_UNIT &)
            // Function       :     public void ExclusiveLogicLock<ArBoxCollision,XCriticalSection>::_LOCK_UNIT::_LOCK_UNIT()
            public BoxCollision c;// = new BoxCollision();          // Data           :     this+0x0, Member, Type: struct Ar
            // 
            public uint refcount;                           // 0x14
            public int thread_id;                           // 0x18
            // Data           :     this+0x1C, Member, Type: class XCriticalSection, lock
            // 
            public long id;                                 // 0x60
            // Function       :     public void Lock()
            // Function       :     public void UnLock()
            // Function       :     public bool IsLocked()
            // Function       :     public void ExclusiveLogicLock<ArBoxCollision,XCriticalSection>::_LOCK_UNIT::~_LOCK_UNIT()
            // Function       :     public struct ExclusiveLogicLock<ArBoxCollision,XCriticalSection>::_LOCK_UNIT & operator=(const struct ExclusiveLogicLock<ArBoxCollision,XCriticalSection>::_LOCK_UNIT &)
            // Function       :     public void * __vecDelDtor(unsigned int)

        }
// UserDefinedType: ExclusiveLogicLock<ArBoxCollision,XCriticalSection>
// Function       :   public void ExclusiveLogicLock<ArBoxCollision,XCriticalSection>(const class ExclusiveLogicLock<ArBoxCollision,XCriticalSection> &)
// Function       :   public void ExclusiveLogicLock<ArBoxCollision,XCriticalSection>::ExclusiveLogicLock<ArBoxCollision,XCriticalSection>()
// Function       :   public int ExclusiveLogicLock<ArBoxCollision,XCriticalSection>::LockLogic(const struct ArBoxCollision &, const char *, int)
        public int LockLogic(BoxCollision c)
        {
            return 0;
    /*
            ExclusiveLogicLock<ArBoxCollision,XCriticalSection> *v4; // esi@1
            ILockVtbl *v5; // eax@1
            int v6; // edi@2
            int result; // eax@10
            int v8; // ecx@11
            unsigned __int8 v9; // cf@11
            int v10; // ebx@11
            ExclusiveLogicLock<ArBoxCollision,XCriticalSection> *v11; // ebx@11
            unsigned int v12; // edi@11
            int v13; // esi@11
            int v14; // eax@17
            int v15; // ecx@18
            XException thisa; // [sp+Ch] [bp-44h]@8
            __int64 myid; // [sp+34h] [bp-1Ch]@11
            ExclusiveLogicLock<ArBoxCollision,XCriticalSection> *v18; // [sp+3Ch] [bp-14h]@1
            volatile LONG *lpAddend; // [sp+40h] [bp-10h]@1
            int v20; // [sp+44h] [bp-Ch]@1
            DWORD my_thread_id; // [sp+48h] [bp-8h]@1
            int i; // [sp+4Ch] [bp-4h]@2
            unsigned int filenamea; // [sp+5Ch] [bp+Ch]@11

            v4 = this;
            v18 = this;
            my_thread_id = Thread. GetCurrentThreadId();
            lpAddend = &v4->m_nWaitingThread;
            InterlockedIncrement(&v4->m_nWaitingThread);
            v5 = v4->m_lock.baseclass_0.vfptr;
            v20 = &v4->m_lock;
            v5->Lock(&v4->m_lock);
            if ( _exclusive_lock_checkDoubleLock() )
            {
                i = 0;
                v6 = &v4->m_lockedRegion[0].lock;
                while ( !(*(*v6 + 16))(v6) || *(v6 - 4) != my_thread_id || !ArBoxCollision::is_subset_of(c, (v6 - 28)) )
                {
                    ++i;
                    v6 += 112;
                    if ( i >= 0x14 )
                        goto LABEL_7;
                }
                InterlockedDecrement(lpAddend);
                v4->m_lock.baseclass_0.vfptr->UnLock(&v4->m_lock);
                result = -1;
            }
            else
            {
        LABEL_7:
                _exclusive_lock_set_lock();
                if ( v4->m_freeBlock < 0 )
                {
                    XException::XException(&thisa, "ExclusiveLogicLock() TOO MANY LOCK!");
                    _CxxThrowException(&thisa, &_TI2_AUXException__);
                }
                LODWORD(myid) = LODWORD(v4->m_id);
                v8 = HIDWORD(v4->m_id);
                v9 = __CFADD__(LODWORD(v4->m_id)++, 1);
                HIDWORD(myid) = v8;
                HIDWORD(v4->m_id) += v9;
                i = v4->m_freeBlock;
                v10 = (v4 + 112 * i);
                (*(*(v10 + 36) + 4))();
                memcpy((v10 + 8), c, 0x14u);
                *(v10 + 32) = my_thread_id;
                *(v10 + 104) = myid;
                *(v10 + 112) = filename;
                *(v10 + 116) = linenumber;
                ++*(v10 + 28);
                v11 = v18;
                v12 = 0;
                v18->m_freeBlock = -1;
                filenamea = 0;
                v13 = &v11->m_lockedRegion[0].lock;
                do
                {
                    if ( *(v13 - 8) )
                    {
                        if ( v12 != i && myid >= *(v13 + 68) && ArBoxCollision::is_exclusive(c, (v13 - 28)) )
                        {
                            ++*(v13 - 8);
                            if ( v11->m_freeBlock < 0 )
                            {
                                v14 = v12 + 1;
                                if ( v12 + 1 < 0x14 )
                                {
                                    v15 = v13 + 104;
                                    while ( *v15 )
                                    {
                                        ++v14;
                                        v15 += 112;
                                        if ( v14 >= 0x14 )
                                            goto LABEL_23;
                                    }
                                    v11->m_freeBlock = v14;
                                }
                            }
        LABEL_23:
                            (*(*v20 + 12))(v20);
                            (*(*v13 + 4))(v13);
                            (*(*v20 + 4))(v20);
                            --*(v13 - 8);
                            (*(*v13 + 12))(v13);
                            v12 = filenamea;
                        }
                    }
                    else
                    {
                        if ( v11->m_freeBlock < 0 )
                            v11->m_freeBlock = v12;
                    }
                    ++v12;
                    v13 += 112;
                    filenamea = v12;
                }
                while ( v12 < 0x14 );
                (*(*v20 + 12))();
                InterlockedIncrement(&v11->m_nLockedThread);
                InterlockedDecrement(lpAddend);
                result = i;
            }
            return result;
    */
        }

// Function       :   public void ExclusiveLogicLock<ArBoxCollision,XCriticalSection>::UnLock(int)
        public void UnLock(int handle)
        {
            if (handle >= 0)
            {
                lock(this)
                {
//                    _exclusive_lock_unset_lock();
                    this.m_lockedRegion[handle].refcount--;
                }
                Interlocked.Decrement(ref this.m_nLockedThread);
            }
        }

// Function       :   public const bool ExclusiveLogicLock<ArBoxCollision,XCriticalSection>::IsLocked(const struct ArBoxCollision &, const bool)
// Function       :   public const long & GetLockedThreadCount()
// Function       :   public const long & GetWaitingThreadCount()
        public int m_nLockedThread;                             // 0x0, Member, Type: volatile long, 
        public int m_nWaitingThread;                            // 0x4, Member, Type: volatile long, 
        public LockUnit[] m_lockedRegion = new LockUnit[20];    // Data           :   this+0x8, Member, Type: struct ExclusiveLogicLock<ArBoxCollision,XCriticalSection>::_LOCK_UNIT[0x14], 
// Data           :   this+0x8C8, Member, Type: class XCriticalSection, m_lock
// 
        public int m_freeBlock;                                 // 0x908, Member, Type: volatile int, 
        public long m_id;                                       // 0x910, Member, Type: volatile __int64, 
// Function       :   private void set_lock()
// Function       :   private void unset_lock()
// Function       :   private bool checkDoubleLock()
// Function       :   public void ExclusiveLogicLock<ArBoxCollision,XCriticalSection>::~ExclusiveLogicLock<ArBoxCollision,XCriticalSection>()
// Function       :   public class ExclusiveLogicLock<ArBoxCollision,XCriticalSection> & operator=(const class ExclusiveLogicLock<ArBoxCollision,XCriticalSection> &)

    }
}
